<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.17">
<meta name="author" content="王斌">
<title>Greenworks 文档</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Greenworks 文档</h1>
<div class="details">
<span id="author" class="author">王斌</span><br>
<span id="email" class="email"><a href="mailto:253498229@qq.com">253498229@qq.com</a></span><br>
</div>
<div id="toc" class="toc2">
<div id="toctitle">目录</div>
<ul class="sectlevel1">
<li><a href="#_成就">1. 成就</a>
<ul class="sectlevel2">
<li><a href="#_解锁成就">1.1. 解锁成就</a></li>
<li><a href="#_查看成就进度">1.2. 查看成就进度</a></li>
<li><a href="#_检查成就是否已解锁">1.3. 检查成就是否已解锁</a></li>
<li><a href="#_取消成就">1.4. 取消成就</a></li>
<li><a href="#_获取所有成就名">1.5. 获取所有成就名</a></li>
<li><a href="#_获取成就数量">1.6. 获取成就数量</a></li>
</ul>
</li>
<li><a href="#_身份认证">2. 身份认证</a>
<ul class="sectlevel2">
<li><a href="#_获取身份验证会话ticket">2.1. 获取身份验证会话ticket</a></li>
<li><a href="#_取消身份ticket">2.2. 取消身份ticket</a></li>
<li><a href="#_获取加密应用ticket">2.3. 获取加密应用ticket</a></li>
<li><a href="#_解密应用ticket">2.4. 解密应用ticket</a></li>
<li><a href="#_是该应用的ticket">2.5. 是该应用的ticket</a></li>
<li><a href="#_获取ticket的发布时间">2.6. 获取ticket的发布时间</a></li>
<li><a href="#_获取ticket对应的steamid">2.7. 获取ticket对应的SteamId</a></li>
<li><a href="#_获取ticket的app_id">2.8. 获取ticket的app id</a></li>
</ul>
</li>
<li><a href="#_steam_云服务">3. Steam 云服务</a>
<ul class="sectlevel2">
<li><a href="#_将文本保存到文件">3.1. 将文本保存到文件</a></li>
<li><a href="#_从文件中读取文本">3.2. 从文件中读取文本</a></li>
<li><a href="#_删除文件">3.3. 删除文件</a></li>
<li><a href="#_将多个文件保存到steam云服务">3.4. 将多个文件保存到Steam云服务</a></li>
<li><a href="#_用户是否开启了云服务">3.5. 用户是否开启了云服务</a></li>
<li><a href="#_该应用是否支持云服务">3.6. 该应用是否支持云服务</a></li>
<li><a href="#_开启关闭云服务">3.7. 开启/关闭云服务</a></li>
<li><a href="#_获取云服务配额">3.8. 获取云服务配额</a></li>
<li><a href="#_获取文件数量">3.9. 获取文件数量</a></li>
<li><a href="#_获取文件名以及大小">3.10. 获取文件名以及大小</a></li>
</ul>
</li>
<li><a href="#_dlc">4. DLC</a>
<ul class="sectlevel2">
<li><a href="#_获取dlc数量">4.1. 获取DLC数量</a></li>
<li><a href="#_通过索引获取dlc数据">4.2. 通过索引获取DLC数据</a></li>
<li><a href="#_dlc是否安装">4.3. DLC是否安装</a></li>
<li><a href="#_安装dlc">4.4. 安装DLC</a></li>
<li><a href="#_卸载dlc">4.5. 卸载DLC</a></li>
</ul>
</li>
<li><a href="#_事件">5. 事件</a>
<ul class="sectlevel2">
<li><a href="#_游戏遮罩层激活或隐藏">5.1. 游戏遮罩层激活或隐藏</a></li>
<li><a href="#_连接到steam服务器">5.2. 连接到Steam服务器</a></li>
<li><a href="#_从steam服务器断开">5.3. 从Steam服务器断开</a></li>
<li><a href="#_连接steam服务器失败">5.4. 连接Steam服务器失败</a></li>
<li><a href="#_steam客户端即将关闭">5.5. Steam客户端即将关闭</a></li>
<li><a href="#_好友状态改变">5.6. 好友状态改变</a></li>
<li><a href="#_头像图片加载完成">5.7. 头像图片加载完成</a></li>
<li><a href="#_收到聊天信息">5.8. 收到聊天信息</a></li>
<li><a href="#_dlc安装完成">5.9. DLC安装完成</a></li>
<li><a href="#_微交易授权响应">5.10. 微交易授权响应</a></li>
<li><a href="#_创建大厅">5.11. 创建大厅</a></li>
<li><a href="#_大厅数据改变">5.12. 大厅数据改变</a></li>
<li><a href="#_进入大厅">5.13. 进入大厅</a></li>
<li><a href="#_收到大厅邀请">5.14. 收到大厅邀请</a></li>
<li><a href="#_加入大厅">5.15. 加入大厅</a></li>
<li><a href="#_加入游戏请求">5.16. 加入游戏请求</a></li>
<li><a href="#_命令行执行url">5.17. 命令行执行URL</a></li>
</ul>
</li>
<li><a href="#_好友">6. 好友</a>
<ul class="sectlevel2">
<li><a href="#_对象">6.1. 对象</a>
<ul class="sectlevel3">
<li><a href="#_好友标识位">6.1.1. 好友标识位</a></li>
<li><a href="#FriendRelationship">6.1.2. 好友关系</a></li>
<li><a href="#_资料变化">6.1.3. 资料变化</a></li>
<li><a href="#_账号类型">6.1.4. 账号类型</a></li>
<li><a href="#_聊天消息类型">6.1.5. 聊天消息类型</a></li>
</ul>
</li>
<li><a href="#SteamID">6.2. SteamID</a></li>
<li><a href="#_方法">6.3. 方法</a>
<ul class="sectlevel3">
<li><a href="#_获取好友数量">6.3.1. 获取好友数量</a></li>
<li><a href="#_根据类型获取所有好友">6.3.2. 根据类型获取所有好友</a></li>
<li><a href="#RequestUserInformation">6.3.3. 请求用户信息</a></li>
<li><a href="#_获取好友小型头像">6.3.4. 获取好友小型头像</a></li>
<li><a href="#_获取好友中型头像">6.3.5. 获取好友中型头像</a></li>
<li><a href="#_获取好友大型头像">6.3.6. 获取好友大型头像</a></li>
<li><a href="#_设置监听好友消息">6.3.7. 设置监听好友消息</a></li>
<li><a href="#_回复好友消息">6.3.8. 回复好友消息</a></li>
<li><a href="#_获取好友消息">6.3.9. 获取好友消息</a></li>
<li><a href="#_获取好友姓名显示名称">6.3.10. 获取好友姓名（显示名称）</a></li>
<li><a href="#_设置当前用户的丰富状态键值">6.3.11. 设置当前用户的丰富状态键/值</a></li>
<li><a href="#_清除丰富状态">6.3.12. 清除丰富状态</a></li>
<li><a href="#_获取好友的丰富状态">6.3.13. 获取好友的丰富状态</a></li>
<li><a href="#SetPlayedWith">6.3.14. 设置和谁一起玩过</a></li>
<li><a href="#_获取好友正在玩的游戏">6.3.15. 获取好友正在玩的游戏</a></li>
<li><a href="#_激活邀请游戏对话框">6.3.16. 激活邀请游戏对话框</a></li>
<li><a href="#_打开特定用户的对话框">6.3.17. 打开特定用户的对话框</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_环境设置">7. 环境设置</a>
<ul class="sectlevel2">
<li><a href="#_初始化_steamworks_api">7.1. 初始化 Steamworks API</a></li>
<li><a href="#_初始化">7.2. 初始化</a></li>
<li><a href="#_判断steam是否正在运行">7.3. 判断steam是否正在运行</a></li>
<li><a href="#_在需要的时候重启应用">7.4. 在需要的时候重启应用</a></li>
<li><a href="#_获取游戏id">7.5. 获取游戏ID</a></li>
<li><a href="#_获取游戏构建id">7.6. 获取游戏构建ID</a></li>
<li><a href="#_获取steamid对象">7.7. 获取SteamId对象</a></li>
<li><a href="#_获取当前游戏语言">7.8. 获取当前游戏语言</a></li>
<li><a href="#_获取当前ui的语言">7.9. 获取当前UI的语言</a></li>
<li><a href="#_获取当前游戏安装目录">7.10. 获取当前游戏安装目录</a></li>
<li><a href="#_获取应用安装目录">7.11. 获取应用安装目录</a></li>
<li><a href="#_获取玩家数量">7.12. 获取玩家数量</a></li>
<li><a href="#_打开steam遮罩层">7.13. 打开Steam遮罩层</a></li>
<li><a href="#_是否启用steam遮罩层">7.14. 是否启用Steam遮罩层</a></li>
<li><a href="#_判断steam是否处于大屏幕模式">7.15. 判断Steam是否处于大屏幕模式</a></li>
<li><a href="#_通过steam遮罩层打开web页面">7.16. 通过Steam遮罩层打开Web页面</a></li>
<li><a href="#_判断是否购买了游戏">7.17. 判断是否购买了游戏</a></li>
<li><a href="#_判断应用是否已安装">7.18. 判断应用是否已安装</a></li>
<li><a href="#_获取图片大小">7.19. 获取图片大小</a></li>
<li><a href="#_获取图像字节">7.20. 获取图像字节</a></li>
<li><a href="#_获取ip所在国家">7.21. 获取IP所在国家</a></li>
<li><a href="#_获取启动命令行">7.22. 获取启动命令行</a></li>
</ul>
</li>
<li><a href="#_统计">8. 统计</a>
<ul class="sectlevel2">
<li><a href="#_获取用户的统计值">8.1. 获取用户的统计值</a></li>
<li><a href="#_获取用户的float格式统计值">8.2. 获取用户的float格式统计值</a></li>
<li><a href="#setStat">8.3. 设置/更新指定统计值</a></li>
<li><a href="#_持久保存统计值">8.4. 持久保存统计值</a></li>
<li><a href="#_重置所有统计状态">8.5. 重置所有统计状态</a></li>
</ul>
</li>
<li><a href="#_工具方法">9. 工具方法</a>
<ul class="sectlevel2">
<li><a href="#_移动文件夹">9.1. 移动文件夹</a></li>
<li><a href="#_创建压缩包">9.2. 创建压缩包</a></li>
<li><a href="#_解压压缩包">9.3. 解压压缩包</a></li>
</ul>
</li>
<li><a href="#_创意工坊">10. 创意工坊</a>
<ul class="sectlevel2">
<li><a href="#_ugcmatchingtype">10.1. UGCMatchingType</a></li>
<li><a href="#_ugcquerytype">10.2. UGCQueryType</a></li>
<li><a href="#_steamugcdetails">10.3. SteamUGCDetails</a></li>
<li><a href="#_userugclist">10.4. UserUGCList</a></li>
<li><a href="#_userugclistsortorder">10.5. UserUGCListSortOrder</a></li>
<li><a href="#_ugcitemstate">10.6. UGCItemState</a></li>
<li><a href="#_共享文件">10.7. 共享文件</a></li>
<li><a href="#_发布工坊文件">10.8. 发布工坊文件</a></li>
<li><a href="#_更新已发布的工坊文件">10.9. 更新已发布的工坊文件</a></li>
<li><a href="#_发布到工坊">10.10. 发布到工坊</a></li>
<li><a href="#_发布更新">10.11. 发布更新</a></li>
<li><a href="#_获取所有文件">10.12. 获取所有文件</a></li>
<li><a href="#_获取用户文件">10.13. 获取用户文件</a></li>
<li><a href="#_下载文件">10.14. 下载文件</a></li>
<li><a href="#_同步文件">10.15. 同步文件</a></li>
<li><a href="#_取消订阅">10.16. 取消订阅</a></li>
<li><a href="#_显示工坊对话框">10.17. 显示工坊对话框</a></li>
<li><a href="#_获取文件状态">10.18. 获取文件状态</a></li>
<li><a href="#_获取文件安装信息">10.19. 获取文件安装信息</a></li>
</ul>
</li>
<li><a href="#_匹配大厅">11. 匹配大厅</a>
<ul class="sectlevel2">
<li><a href="#LobbyType">11.1. 大厅类型对象</a></li>
<li><a href="#_创建匹配大厅">11.2. 创建匹配大厅</a></li>
<li><a href="#_设置大厅数据">11.3. 设置大厅数据</a></li>
<li><a href="#_获取大厅数据">11.4. 获取大厅数据</a></li>
<li><a href="#_删除大厅数据">11.5. 删除大厅数据</a></li>
<li><a href="#_加入匹配大厅">11.6. 加入匹配大厅</a></li>
<li><a href="#_退出匹配大厅">11.7. 退出匹配大厅</a></li>
<li><a href="#_根据索引获得大厅信息">11.8. 根据索引获得大厅信息</a></li>
<li><a href="#_根据索引获得成员信息">11.9. 根据索引获得成员信息</a></li>
<li><a href="#_获取大厅所有者">11.10. 获取大厅所有者</a></li>
<li><a href="#_获取大厅中的用户数量">11.11. 获取大厅中的用户数量</a></li>
<li><a href="#_邀请其他用户进入大厅">11.12. 邀请其他用户进入大厅</a></li>
<li><a href="#_设置大厅是否开放">11.13. 设置大厅是否开放</a></li>
<li><a href="#_变更大厅所有者">11.14. 变更大厅所有者</a></li>
<li><a href="#_设置大厅类型">11.15. 设置大厅类型</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_成就">1. 成就</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_解锁成就">1.1. 解锁成就</h3>
<div class="paragraph">
<p><strong>greenworks.activateAchievement(achievement, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>achievement</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>achievement参数表示游戏中尚未解锁的成就。</p>
</div>
</div>
<div class="sect2">
<h3 id="_查看成就进度">1.2. 查看成就进度</h3>
<div class="paragraph">
<p><strong>greenworks.indicateAchievementProgress(achievement, current, max)</strong></p>
</div>
<div class="paragraph">
<p>为用户弹出一个带有当前成就进度的通知。</p>
</div>
<div class="paragraph">
<p>调用这个函数不会修改进度或者是解锁成就，如果想的话请使用 <a href="#setStat">设置/更新指定统计值</a>。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>achievement</code> String: 该成就调用API使用的名称。</p>
</li>
<li>
<p><code>current</code> Number: 当前进度。</p>
</li>
<li>
<p><code>max</code> Number: 成就解锁所需的进度。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>成功时返回 <code>true</code>，否则返回 <code>false</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_检查成就是否已解锁">1.3. 检查成就是否已解锁</h3>
<div class="paragraph">
<p><strong>greenworks.getAchievement(achievement, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>achievement</code> String: 该成就调用API使用的名称。</p>
</li>
<li>
<p><code>success_callback</code> Function(is_achieved)</p>
<div class="ulist">
<ul>
<li>
<p><code>is_achieved</code> Boolean: 该成就是否已经解锁。</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>检查 <code>成就</code> 是否已经解锁。</p>
</div>
</div>
<div class="sect2">
<h3 id="_取消成就">1.4. 取消成就</h3>
<div class="paragraph">
<p><strong>greenworks.clearAchievement(achievement, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>achievement</code> String - 需要取消的成就</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_获取所有成就名">1.5. 获取所有成就名</h3>
<div class="paragraph">
<p><strong>greenworks.getAchievementNames()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>String[]</code>，代表游戏中所有的成就名（调用API使用的，和成就标题不一定相同）。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取成就数量">1.6. 获取成就数量</h3>
<div class="paragraph">
<p><strong>greenworks.getNumberOfAchievements()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 值，表示游戏中所有成就的数量。</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_身份认证">2. 身份认证</h2>
<div class="sectionbody">
<div class="paragraph">
<p>身份认证API提供了一些工具来认证Steam用户的身份以及判断用户是否拥有应用的所有权。</p>
</div>
<div class="paragraph">
<p><strong>Note</strong>: 身份认证API需要一个额外的动态库。 请从Steamworks SDK (<code>&lt;steam_sdk-path&gt;/public/steam/lib/</code> 目录)复制 <code>sdkencryptedappticket.dll</code>/<code>libsdkencryptedappticket.dylib</code>/<code>libsdkencryptedappticket.so</code> 文件到应用文件夹 <code>&lt;greenworks&gt;/lib</code> 中。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">var greenworks = require('./greenworks');

greenworks.init();

greenworks.getEncryptedAppTicket('test_content', function(ticket) {
    console.log("ticket: " + ticket.toString('hex'));
    // Specify the secret key.
    var key = new Buffer(32);
    // TODO: you must initialize Buffer key with the secret key of your game here,
    // e.g. key = new Buffer([0x0a, ..., 0x0b]).
    assert(key.length == greenworks.EncryptedAppTicketSymmetricKeyLength)
    var decrypted_app_ticket = greenworks.decryptAppTicket(ticket, key);
    if (decrypted_app_ticket) {
        console.log(greenworks.isTicketForApp(decrypted_app_ticket,
            greenworks.getAppId()));
        console.log(greenworks.getTicketAppId(decrypted_app_ticket));
        console.log(greenworks.getTicketSteamId(decrypted_app_ticket));
        console.log(greenworks.getTicketIssueTime(decrypted_app_ticket));
    }
}, function(err) { throw err; });</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_获取身份验证会话ticket">2.1. 获取身份验证会话ticket</h3>
<div class="paragraph">
<p><strong>greenworks.getAuthSessionTicket(success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>success_callback</code> Function(ticket)</p>
<div class="ulist">
<ul>
<li>
<p><code>ticket</code> Object:</p>
<div class="ulist">
<ul>
<li>
<p><code>ticket</code> Buffer: <code>ticket</code> 的值。</p>
</li>
<li>
<p><code>handle</code> Integer: 该ticket返回的 <code>handle</code>。</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获取要发送给希望对您进行身份验证的实体的ticket。</p>
</div>
<div class="paragraph">
<p>ticket buffer 可以像 <code>ticket.toString('hex')</code> 这样在 Web API <code>ISteamUserAuth/AuthenticateUserTicket</code> 中被使用，这样就可以从游戏服务器安全的获得授权的Steam ID。 如果票证未被使用，则需要使用 <code>handle</code> 来将ticket作废。</p>
</div>
<div class="paragraph">
<p>注意一旦创建ticket的进程终止了，那么生成出来的ticket就无效了。 所以如果您想要在某些临时进程中创建ticket，请确保这些ticket在身份验证结束前保持有效！</p>
</div>
</div>
<div class="sect2">
<h3 id="_取消身份ticket">2.2. 取消身份ticket</h3>
<div class="paragraph">
<p><strong>greenworks.cancelAuthTicket(ticket_handle)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>ticket_handle</code> Integer: 该ticket返回的 <code>handle</code>。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将请求的session ticket 作废。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取加密应用ticket">2.3. 获取加密应用ticket</h3>
<div class="paragraph">
<p><strong>greenworks.getEncryptedAppTicket(user_data, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>user_data</code> String: 将要加密到ticket中的任意值。将会以utf-8编码存储在ticket中。</p>
</li>
<li>
<p><code>success_callback</code> Function(encrypted_ticket)</p>
<div class="ulist">
<ul>
<li>
<p><code>encrypted_ticket</code> Buffer: 加密过的ticket。</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>加密ticket可以用来从客户端获取认证的Steam Id，而无需向Steam的API服务器发送网络请求。 这些ticket可以通过加密应用的ticket秘钥来进行解密。 在解密之后，可以通过Steamworks SDK中提供的加密应用ticket库，从ticket中查看用户的Steam ID、App ID、以及 VAC ban状态。</p>
</div>
</div>
<div class="sect2">
<h3 id="_解密应用ticket">2.4. 解密应用ticket</h3>
<div class="paragraph">
<p><strong>greenworks.decryptAppTicket(encrypted_ticket, decryption_key)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>encrypted_ticket</code> Buffer: 加密过的ticket。</p>
</li>
<li>
<p><code>decryption_key</code> Buffer: 用于解密的秘钥。其长度应该是 <code>greenworks.EncryptedAppTicketSymmetricKeyLength</code>。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>使用解密key可以堆加密过的应用ticket进行解密。 如果解密成功则会返回一个 <code>Buffer</code>；否则会返回 <code>Null</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_是该应用的ticket">2.5. 是该应用的ticket</h3>
<div class="paragraph">
<p><strong>greenworks.isTicketForApp(decrypted_ticket, app_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>decrypted_ticket</code> Buffer: 解密过的ticket。</p>
</li>
<li>
<p><code>app_id</code> Integer: 这个app的id。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示解密ticket是否适用于该应用。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取ticket的发布时间">2.6. 获取ticket的发布时间</h3>
<div class="paragraph">
<p><strong>greenworks.getTicketIssueTime(decrypted_ticket)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>decrypted_ticket</code> Buffer: 解密过的ticket。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code>，表示该ticket的发布时间。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取ticket对应的steamid">2.7. 获取ticket对应的SteamId</h3>
<div class="paragraph">
<p><strong>greenworks.getTicketSteamId(decrypted_ticket)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>decrypted_ticket</code> Buffer: 解密过的ticket。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <a href="#SteamID">SteamID</a> 对象，表示该ticket的steam id。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取ticket的app_id">2.8. 获取ticket的app id</h3>
<div class="paragraph">
<p><strong>greenworks.getTicketAppId(decrypted_ticket)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>decrypted_ticket</code> Buffer: 解密过的ticket。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> ，表示该ticket的app id。</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_steam_云服务">3. Steam 云服务</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_将文本保存到文件">3.1. 将文本保存到文件</h3>
<div class="paragraph">
<p><strong>greenworks.saveTextToFile(file_name, file_content, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>file_name</code> String</p>
</li>
<li>
<p><code>file_content</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_从文件中读取文本">3.2. 从文件中读取文本</h3>
<div class="paragraph">
<p><strong>greenworks.readTextFromFile(file_name, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>file_name</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function(file_content)</p>
<div class="ulist">
<ul>
<li>
<p><code>file_content</code> String: 代表对应 <code>file_name</code> 文件的文本内容。</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_删除文件">3.3. 删除文件</h3>
<div class="paragraph">
<p><strong>greenworks.deleteFile(file_name, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>file_name</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_将多个文件保存到steam云服务">3.4. 将多个文件保存到Steam云服务</h3>
<div class="paragraph">
<p><strong>greenworks.saveFilesToCloud(files_path, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>files_path</code> Array of String: 文件在本地的路径。</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将多个本地文件写入Steam云服务。</p>
</div>
</div>
<div class="sect2">
<h3 id="_用户是否开启了云服务">3.5. 用户是否开启了云服务</h3>
<div class="paragraph">
<p><strong>greenworks.isCloudEnabledForUser()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示当前Steam账户是否开启了云服务。</p>
</div>
</div>
<div class="sect2">
<h3 id="_该应用是否支持云服务">3.6. 该应用是否支持云服务</h3>
<div class="paragraph">
<p><strong>greenworks.isCloudEnabled()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示当前应用是否支持云服务。 该结果与 <code>greenworks.isCloudEnabledForUser()</code> 无关。 请记住，用户对应用特殊设定的优先级高于全局默认的设置。 因此，您可能需要首先检查 <code>isCloudEnabledForUser()</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_开启关闭云服务">3.7. 开启/关闭云服务</h3>
<div class="paragraph">
<p><strong>greenworks.enableCloud(flag)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>flag</code> Boolean</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>开启或关闭当前应用的云服务功能。 请记住，如果您的应用程序在最顶层关闭了它，那么应用将不会将任何内容同步Steam云（请参阅 <code>greenworks.isCloudEnabledForUser()</code>）。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取云服务配额">3.8. 获取云服务配额</h3>
<div class="paragraph">
<p><strong>greenworks.getCloudQuota(success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>success_callback</code> Function(total_bytes, available_bytes)</p>
<div class="ulist">
<ul>
<li>
<p><code>total_bytes</code> uint64 String: 配额总字节数</p>
</li>
<li>
<p><code>available_bytes</code> uint64 String: 配额的最大可用字节数</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_获取文件数量">3.9. 获取文件数量</h3>
<div class="paragraph">
<p><strong>greenworks.getFileCount()</strong></p>
</div>
<div class="paragraph">
<p>获取Steam云服务中的文件数量。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取文件名以及大小">3.10. 获取文件名以及大小</h3>
<div class="paragraph">
<p><strong>greenworks.getFileNameAndSize(index)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>index</code> Integer: 文件的索引</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Returns an <code>Object</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>name</code> String: 文件名</p>
</li>
<li>
<p><code>size</code> Integer: 文件大小</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_dlc">4. DLC</h2>
<div class="sectionbody">
<div class="dlist">
<dl>
<dt class="hdlist1"><strong>DLC</strong></dt>
<dd>
<p>Downloadable Content的简写，即可下载内容。</p>
</dd>
</dl>
</div>
<div class="sect2">
<h3 id="_获取dlc数量">4.1. 获取DLC数量</h3>
<div class="paragraph">
<p><strong>greenworks.getDLCCount()</strong></p>
</div>
<div class="paragraph">
<p>获取当前运行中应用的DLC数量。</p>
</div>
</div>
<div class="sect2">
<h3 id="_通过索引获取dlc数据">4.2. 通过索引获取DLC数据</h3>
<div class="paragraph">
<p><strong>greenworks.getDLCDataByIndex(index)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>index</code> Integer: 该DLC的索引，其值的范围应该在 0 到 <code>greenworks.getDLCCount</code> 之间。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>如果找不到索引匹配的DLC则返回 <code>undefined</code>，否则会返回一个对象，包含下面的内容:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>appId</code> Integer: 该DLC的APPID。</p>
</li>
<li>
<p><code>available</code> Boolean: 该DLC当前是否可用的标志位。</p>
</li>
<li>
<p><code>name</code> String: 该DLC的名称。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_dlc是否安装">4.3. DLC是否安装</h3>
<div class="paragraph">
<p><strong>greenworks.isDLCInstalled(dlc_app_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>dlc_app_id</code> Integer: 该DLC的APPID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>查看用户是否拥有这个DLC以及DLC是否已安装。</p>
</div>
</div>
<div class="sect2">
<h3 id="_安装dlc">4.4. 安装DLC</h3>
<div class="paragraph">
<p><strong>greenworks.installDLC(dlc_app_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>dlc_app_id</code> Integer: 该DLC的APPID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>安装指定的DLC。</p>
</div>
</div>
<div class="sect2">
<h3 id="_卸载dlc">4.5. 卸载DLC</h3>
<div class="paragraph">
<p><strong>greenworks.uninstallDLC(dlc_app_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>dlc_app_id</code> Integer: 该DLC的APPID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>卸载指定的DLC。</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_事件">5. 事件</h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>greenworks</code> 是一个事件回调器，负责监听Steam事件。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">var greenworks = require('docs/greenworks.json');

// 需要在使用greenworks的API之前进行初始化
greenworks.init();

function log(msg) {
    console.log(msg);
}

greenworks.on('game-overlay-activated', function(is_active) {
    if (is_active)
        log('game overlay is activated');
    else
        log('game overlay is deactivated');
});

greenworks.on('steam-servers-connected', function() { log('connected')});
greenworks.on('steam-servers-disconnected', function() { log('disconnected')});
greenworks.on('steam-server-connect-failure', function() { log('connected failure')});
greenworks.on('steam-shutdown', function() { log('shutdown')});</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_游戏遮罩层激活或隐藏">5.1. 游戏遮罩层激活或隐藏</h3>
<div class="paragraph">
<p>事件: 'game-overlay-activated'</p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>is_active</code> Boolean: 表示游戏覆盖层是激活还是隐藏。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>当游戏遮罩层激活或隐藏时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_连接到steam服务器">5.2. 连接到Steam服务器</h3>
<div class="paragraph">
<p>事件: 'game-servers-connected'</p>
</div>
<div class="paragraph">
<p>当游戏连接到Steam服务器时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_从steam服务器断开">5.3. 从Steam服务器断开</h3>
<div class="paragraph">
<p>事件: 'game-servers-disconnected'</p>
</div>
<div class="paragraph">
<p>当游戏从Steam服务器断开连接时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_连接steam服务器失败">5.4. 连接Steam服务器失败</h3>
<div class="paragraph">
<p>事件: 'game-server-connect-failure'</p>
</div>
<div class="paragraph">
<p>当游戏连接Steam服务器失败时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_steam客户端即将关闭">5.5. Steam客户端即将关闭</h3>
<div class="paragraph">
<p>事件: 'steam-shutdown'</p>
</div>
<div class="paragraph">
<p>当Steam客户端即将关闭时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_好友状态改变">5.6. 好友状态改变</h3>
<div class="paragraph">
<p>事件: 'persona-state-change'</p>
</div>
<div class="paragraph">
<p>当一个好友的状态改变时（与 <code>greenworks.requestUserInformation</code> 一起使用）触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_头像图片加载完成">5.7. 头像图片加载完成</h3>
<div class="paragraph">
<p>事件: 'avatar-image-loaded'</p>
</div>
<div class="paragraph">
<p>如果图像还不可用，那么在上一个使用 <code>getLargeFriendAvatar()</code> 加载一个头像大图时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_收到聊天信息">5.8. 收到聊天信息</h3>
<div class="paragraph">
<p>事件: 'game-connected-friend-chat-message'</p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steam_id</code> String: 一个64位steam ID.</p>
</li>
<li>
<p><code>message_id</code> Integer</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>当用户收到聊天消息时触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_dlc安装完成">5.9. DLC安装完成</h3>
<div class="paragraph">
<p>事件: 'dlc-installed'</p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>dlc_app_id</code> Integer: DLC的APPID</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>当用户获得DLC的所有权，或者是安装了DLC之后触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_微交易授权响应">5.10. 微交易授权响应</h3>
<div class="paragraph">
<p>事件: 'micro-txn-authorization-response'</p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>app_id</code> Integer: 此次微交易的AppID。</p>
</li>
<li>
<p><code>ord_id</code> String: 为此次微交易提供的的64位OrderID。</p>
</li>
<li>
<p><code>authorized</code> Boolean: 用户是否授权了交易。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>当用户响应微交易授权请求后触发。</p>
</div>
</div>
<div class="sect2">
<h3 id="_创建大厅">5.11. 创建大厅</h3>
<div class="paragraph">
<p>事件: 'lobby-created'</p>
</div>
<div class="paragraph">
<p>在尝试创建大厅之后触发。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamMatchmaking#LobbyCreated_t">Steam docs</a></p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>m_eResult</code> Integer: 大厅创建结果。</p>
</li>
<li>
<p><code>m_ulSteamIDLobby</code> String: 该大厅的Steam ID。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_大厅数据改变">5.12. 大厅数据改变</h3>
<div class="paragraph">
<p>事件: 'lobby-data-update'</p>
</div>
<div class="paragraph">
<p>大厅数据改变时触发。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamMatchmaking#king#LobbyDataUpdate_t">Steam docs</a></p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>m_ulSteamIDLobby</code> String: 该大厅的Steam ID。</p>
</li>
<li>
<p><code>m_ulSteamIDMember</code> String: 房间成员或房间本身数据改变时的Steam ID.</p>
</li>
<li>
<p><code>m_bSuccess</code> Boolean: 大厅数据是否成功改变。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_进入大厅">5.13. 进入大厅</h3>
<div class="paragraph">
<p>事件: 'lobby-enter'</p>
</div>
<div class="paragraph">
<p>尝试进入大厅时触发。 收到这条消息后就可以使用大厅数据。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamMatchmaking#king#LobbyEnter_t">Steam docs</a></p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>m_ulSteamIDLobby</code> String: 该大厅的Steam ID。</p>
</li>
<li>
<p><code>m_rgfChatPermissions</code> Integer: 未使用 - 使用为0。</p>
</li>
<li>
<p><code>m_bLocked</code> Boolean: 如果是true，则只有被邀请的用户才可以加入。</p>
</li>
<li>
<p><code>m_EChatRoomEnterResponse</code> Integer: 这实际上是一个 <a href="https://partner.steamgames.com/doc/api/steam_api#EChatRoomEnterResponse">EChatRoomEnterResponse</a> 值。 如果成功加入大厅就是 k_EChatRoomEnterResponseSuccess，否则是 k_EChatRoomEnterResponseError。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_收到大厅邀请">5.14. 收到大厅邀请</h3>
<div class="paragraph">
<p>事件: 'lobby-invite'</p>
</div>
<div class="paragraph">
<p>收到邀请时触发。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamMatchmaking#king#LobbyInvite_t">Steam docs</a></p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>m_ulSteamIDUser</code> String: 发送邀请的人的Steam ID。</p>
</li>
<li>
<p><code>m_ulSteamIDLobby</code> String: 邀请我们的Steam ID。</p>
</li>
<li>
<p><code>m_ulGameID</code> String: 邀请我们的大厅的Game ID。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_加入大厅">5.15. 加入大厅</h3>
<div class="paragraph">
<p>事件: 'lobby-join-requested'</p>
</div>
<div class="paragraph">
<p>当用户从朋友列表或被邀请后尝试加入大厅时触发。 当连接到指定大厅的时候，游戏客户端会收到这条消息。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamFriends#GameLobbyJoinRequested_t">Steam docs</a></p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>m_steamIDLobby</code> String: 要连接到的大厅的Steam ID。</p>
</li>
<li>
<p><code>m_steamIDFriend</code> String: 他们是通过那个朋友加入的。如果不是直接通过朋友加入则会无效。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_加入游戏请求">5.16. 加入游戏请求</h3>
<div class="paragraph">
<p>事件: 'rich-presence-join-requested'</p>
</div>
<div class="paragraph">
<p>当用户尝试从好友列表中加入游戏时触发，其使用的是富消息状态。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamFriends#GameRichPresenceJoinRequested_t">Steam docs</a></p>
</div>
<div class="paragraph">
<p>Returns:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>m_steamIdFriend</code> String: 他们是通过那个朋友加入的。如果不是直接通过朋友加入则会无效。</p>
</li>
<li>
<p><code>m_rgchConnect</code> String: 与 "连接" 富消状态息key关联的值。</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_命令行执行url">5.17. 命令行执行URL</h3>
<div class="paragraph">
<p>事件: 'new-url-launch-parameters'</p>
</div>
<div class="paragraph">
<p>在游戏已经运行时，当用户使用命令行执行steam url或查询参数（如  <code>steam://run/&lt;appid&gt;//?param1=value1;param2=value2;param3=value3;</code> ）后触发。 新的参数可以使用 <a href="https://partner.steamgames.com/doc/api/ISteamApps#GetLaunchCommandLine">GetLaunchCommandLine</a> 以及 <a href="https://partner.steamgames.com/doc/api/ISteamApps#GetLaunchQueryParam">GetLaunchQueryParam</a> 查询。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamApps#NewUrlLaunchParameters_t">Steam docs</a></p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_好友">6. 好友</h2>
<div class="sectionbody">
<div class="paragraph">
<p>好友API可以让您获取好友列表数据以及用户的基本信息。</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">var greenworks = require('./greenworks');

if (greenworks.init()) {
  greenworks.on('persona-state-change',
                function(steam_id, persona_change_flag) {
    if (persona_change_flag == greenworks.PersonaChange.Name)
      console.log("Change to new name: " + steam_id.getPersonaName());
  });

  greenworks.on('game-connected-friend-chat-message',
                function(steam_id, message_id) {
    var info = greenworks.getFriendMessage(steam_id.getRawSteamID(), message_id,
                                           2048);
    if (info.chatEntryType == greenworks.ChatEntryType.ChatMsg) {
      var message = info.message;
      console.log("Receive a message from " + steam_id.getPersonaName() + ": " +
                  message);
      greenworks.replyToFriendMessage(steam_id.getRawSteamID(),
                                      "Hello, I received your message.");
    }
  });

  // Listen to messages from friends.
  greenworks.setListenForFriendsMessage(true);

  // Get the number of regular friends.
  console.log(greenworks.getFriendCount(greenworks.FriendFlags.Immediate));
  var friends = greenworks.getFriends(greenworks.FriendFlags.Immediate);
  for (var i = 0; i &lt; friends.length; ++i) {
    console.log(friends[i].getPersonaName());
    greenworks.requestUserInformation(friends[i].getRawSteamID(), true);
  }
}</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_对象">6.1. 对象</h3>
<div class="sect3">
<h4 id="_好友标识位">6.1.1. 好友标识位</h4>
<div class="paragraph">
<p><strong>greenworks.FriendFlags</strong></p>
</div>
<div class="paragraph">
<p>代表SteamSDK中的 <code>EFriendFlags</code>，用于获取一个枚举好友列表，或者是快速查看用户之间的关系。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>None</code> (0.无)</p>
</li>
<li>
<p><code>Blocked</code> (1.当前用户已经忽略的用户)</p>
</li>
<li>
<p><code>FriendshipRequested</code> (2.已经向当前用户发送好友申请的用户)</p>
</li>
<li>
<p><code>Immediate</code> (4.当前用户的"常规"好友)</p>
</li>
<li>
<p><code>ClanMember</code> (8.与当前用户同属于一个Steam小组的用户)</p>
</li>
<li>
<p><code>OnGameServer</code> (16.与当前用户在同一个游戏服务器上的好友;通过 <a href="#SetPlayedWith">设置和谁一起玩过</a> 设置)</p>
</li>
<li>
<p><code>RequestingFriendship</code> (128.当前用户已经向其发送好友申请的用户)</p>
</li>
<li>
<p><code>RequestingInfo</code> (256.在调用 <a href="#RequestUserInformation">请求用户信息</a> 后正在发送自己额外信息的用户)</p>
</li>
<li>
<p><code>Ignored</code> (512.当前用户已经屏蔽与他们联系的用户)</p>
</li>
<li>
<p><code>IgnoredFriend</code> (1024.屏蔽当前用户的用户;但是当前用户仍然知道他们)</p>
</li>
<li>
<p><code>ChatMember</code> (4096.在同一个聊天中的用户)</p>
</li>
<li>
<p><code>All</code> (65535.返回所有好友的标识位)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="FriendRelationship">6.1.2. 好友关系</h4>
<div class="paragraph">
<p><strong>greenworks.FriendRelationship</strong></p>
</div>
<div class="paragraph">
<p>代表SteamSDK中的 <code>EFriendRelationship</code>（和其它用户的关系）。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>None</code> (0.没有关系的用户)</p>
</li>
<li>
<p><code>Blocked</code> (1.用户刚刚点击了好友邀请上的忽略。这不会被存储)</p>
</li>
<li>
<p><code>RequestRecipient</code> (2.已经申请与当前用户成为朋友的用户)</p>
</li>
<li>
<p><code>Friend</code> (3."常规"好友)</p>
</li>
<li>
<p><code>RequestInitiator</code> (4.当前用户已经发送好友申请的用户)</p>
</li>
<li>
<p><code>Ignored</code> (5.当前用户已经明确屏蔽此用户发表的评论、聊天等。这是会被存储的)</p>
</li>
<li>
<p><code>IgnoredFriend</code> (6.已经屏蔽当前用户的用户)</p>
</li>
<li>
<p><code>Suggested</code> (7.已废弃&#8201;&#8212;&#8201;未使用)</p>
</li>
<li>
<p><code>Max</code> (8.未使用&#8201;&#8212;&#8201;用于循环判断朋友关系的总数)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_资料变化">6.1.3. 资料变化</h4>
<div class="paragraph">
<p><strong>greenworks.PersonaChange</strong></p>
</div>
<div class="paragraph">
<p>代表SteamSDK中的 <code>EPersonaChange</code>，用于 <code>persona-state-change</code> 事件。</p>
</div>
<div class="paragraph">
<p>它描述了客户端最近了解到发生了哪些变化，所以在启动时，你会看到每个好友的名字、头像以及好友关系的变化。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Name</code> (1)</p>
</li>
<li>
<p><code>Status</code> (2)</p>
</li>
<li>
<p><code>ComeOnline</code> (4)</p>
</li>
<li>
<p><code>GoneOffline</code> (8)</p>
</li>
<li>
<p><code>GamePlayed</code> (16)</p>
</li>
<li>
<p><code>GameServer</code> (32)</p>
</li>
<li>
<p><code>Avatar</code> (64)</p>
</li>
<li>
<p><code>JoinedSource</code> (128)</p>
</li>
<li>
<p><code>LeftSource</code> (256)</p>
</li>
<li>
<p><code>RelationshipChanged</code> (512)</p>
</li>
<li>
<p><code>NameFirstSet</code> (1024)</p>
</li>
<li>
<p><code>FacebookInfo</code> (2048)</p>
</li>
<li>
<p><code>NickName</code> (4096)</p>
</li>
<li>
<p><code>SteamLevel</code> (8192)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_账号类型">6.1.4. 账号类型</h4>
<div class="paragraph">
<p><strong>greenworks.AccountType</strong></p>
</div>
<div class="paragraph">
<p>代表SteamSDK中的 <code>EAccountType</code>（Steam 账户类型）。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Invalid</code> (0.用于无效 Steam ID)</p>
</li>
<li>
<p><code>Individual</code> (1.普通用户帐户)</p>
</li>
<li>
<p><code>Multiseat</code> (2.多座位（如网吧）帐户)</p>
</li>
<li>
<p><code>GameServer</code> (3.持久（非匿名）游戏服务器帐户)</p>
</li>
<li>
<p><code>AnonymousGameServer</code> (4.匿名游戏服务器帐户)</p>
</li>
<li>
<p><code>Pending</code> (5.待处理)</p>
</li>
<li>
<p><code>ContentServer</code> (6.Valve 内部内容服务器帐户)</p>
</li>
<li>
<p><code>Clan</code> (7.Steam 组（群组）)</p>
</li>
<li>
<p><code>Chat</code> (8.Steam 组聊天或大厅)</p>
</li>
<li>
<p><code>ConsoleUser</code> (9.虚拟 Steam ID，用于 PS3 本地 PSN 帐户或 360 Live 帐户等)</p>
</li>
<li>
<p><code>AnonymousUser</code> (10.匿名用户帐户 （用来创建帐户或重置密码）)</p>
</li>
<li>
<p><code>Max</code> (11.此字段最多 16 项)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_聊天消息类型">6.1.5. 聊天消息类型</h4>
<div class="paragraph">
<p><strong>greenworks.ChatEntryType</strong></p>
</div>
<div class="paragraph">
<p>Represents Steam SDK <code>EChatEntryType</code> (previously was only friend-to-friend message types).</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Invalid</code> （0无效。）</p>
</li>
<li>
<p><code>ChatMsg</code> （1来自其他用户的普通文本消息。）</p>
</li>
<li>
<p><code>Typing</code> （2另一用户正在输入，不用于多用户群聊。）</p>
</li>
<li>
<p><code>InviteGame</code> （3其他用户邀请进入当前进行的游戏。）</p>
</li>
<li>
<p><code>Emote</code> （4文本表情包（已弃用，应视作 ChatMsg 处理）。）</p>
</li>
<li>
<p><code>LeftConversation</code> （6一名用户离开了对话（关闭了对话窗口）。）</p>
</li>
<li>
<p><code>Entered</code> （7用户加入聊天，用于多用户群聊与组聊天。）</p>
</li>
<li>
<p><code>WasKicked</code> （8用户被踢出（数据：执行踢出操作的用户的 Steam ID）。）</p>
</li>
<li>
<p><code>WasBanned</code> （9用户被封（数据：执行封禁操作的用户的 Steam ID）。）</p>
</li>
<li>
<p><code>Disconnected</code> （10用户掉线。）</p>
</li>
<li>
<p><code>HistoricalChat</code> （11来自用户的聊天历史记录的聊天消息或离线消息。）</p>
</li>
<li>
<p><code>LinkBlocked</code> （14聊天过滤器移除了一个链接。）</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="SteamID">6.2. SteamID</h3>
<div class="paragraph">
<p>代表 <code>CSteamID</code> 的对象。</p>
</div>
<div class="paragraph">
<p>`SteamID`对象有如下方法:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isAnonymous()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个匿名账号。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isAnonymousGameServer()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否为匿名游戏服务器id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isAnonymousGameServerLogin()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Returns whether it is an anonymous game server login that will be filled in.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isAnonymousUser()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是匿名用户账号 （用于创建账户或重置密码）。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isChatAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个聊天account id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isClanAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个小组account id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isConsoleUserAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是PSN好友账号的虚拟SteamID。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isContentServerAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个内容服务器的account id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isGameServerAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个游戏服务器的account id （要么是持久，要么是匿名）。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isIndividualAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个单独用户的account id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isPersistentGameServerAccount()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否是一个持久（非匿名）的游戏服务器account id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isLobby()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否为聊天account id。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getAccountID()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个代表用户身份的 <code>Integer</code> 值。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getRawSteamID()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回代表SteamID的 <code>String</code> 值（将CSteamID转换为64位的形式）。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getAccountType()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回 <code>greenworks.AccountType</code> 字段。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.isValid()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回是否为有效account。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getStaticAccountKey()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个代表64位静态account key的字符串。</p>
</div>
<div class="paragraph">
<p>他会将SteamID中静态的部分转换为64位的形式。 对于多座位用户（比如网吧用户），该账户的所有实例都具有相同的静态account key，因此可以通过静态account key将他们分在一组中。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getPersonaName()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个代表用户名字的字符串。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getNickname()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回当前用户为指定玩家设置的昵称 <code>String</code>。 如果没有为该玩家设置昵称，则为空。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getRelationship()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code><a href="#FriendRelationship">Integer</a></code> 代表与用户关系的。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>SteamID.getSteamLevel()</strong></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 代表steam等级的。</p>
</div>
</div>
<div class="sect2">
<h3 id="_方法">6.3. 方法</h3>
<div class="sect3">
<h4 id="_获取好友数量">6.3.1. 获取好友数量</h4>
<div class="paragraph">
<p><strong>greenworks.getFriendCount(friend_flag)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>friend_flag</code> greenworks.FriendFlags</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 表示好友的人数。</p>
</div>
</div>
<div class="sect3">
<h4 id="_根据类型获取所有好友">6.3.2. 根据类型获取所有好友</h4>
<div class="paragraph">
<p><strong>greenworks.getFriends(friend_flag)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>friend_flag</code> greenworks.FriendFlags</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回 <a href="#SteamID">SteamID</a> 对象数组，每个 <code>SteamID</code> 表示一个朋友。</p>
</div>
</div>
<div class="sect3">
<h4 id="RequestUserInformation">6.3.3. 请求用户信息</h4>
<div class="paragraph">
<p><strong>greenworks.requestUserInformation(raw_steam_id, require_name_only)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 64位形式的SteamId，从 <code>SteamID.getRawSteamID()</code> 获得</p>
</li>
<li>
<p><code>require_name_only</code> Boolean:只返回昵称（true）吗？ 还是同时返回名称和头像（false）？</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>请求指定用户的昵称及头像（可选）。 如果返回 true 表示已请求数据，收到数据时将会触发 <code>persona-state-changed</code> 回调； 如果返回 false 表示已经有了该用户的详细数据，需要这些信息的函数可立即使用。</p>
</div>
<div class="paragraph">
<p>如果 <code>require_name_only</code> 是true，则会下载该用户的头像（下载头像非常缓慢，并且会改动本地缓存，所以如果不需要头像，请勿发出请求）。</p>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友小型头像">6.3.4. 获取好友小型头像</h4>
<div class="paragraph">
<p><strong>greenworks.getSmallFriendAvatar(raw_steam_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 64位格式的SteamId，从 <code>SteamID.getRawSteamID()</code> 获得</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获取小型（32*32 像素）头像。 返回的integer型句柄可以被 <code>getImageRGBA()</code> 使用； 如果未设置头像则返回 0。</p>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友中型头像">6.3.5. 获取好友中型头像</h4>
<div class="paragraph">
<p><strong>greenworks.getMediumFriendAvatar(raw_steam_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 64位格式的SteamId，从 <code>SteamID.getRawSteamID()</code> 获得</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获取中型（64*64 像素）头像。 返回的integer型句柄可以被 <code>getImageRGBA()</code> 使用； 如果未设置头像则返回 0。</p>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友大型头像">6.3.6. 获取好友大型头像</h4>
<div class="paragraph">
<p><strong>greenworks.getLargeFriendAvatar(raw_steam_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 64位格式的SteamId，从 <code>SteamID.getRawSteamID()</code> 获得</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获取大型（128*128 像素）头像。 返回的integer型句柄可以被 <code>getImageRGBA()</code> 使用； 如果未设置头像则返回 0； 如果图像数据尚未载入并请求下载，返回 -1。 在此情况下，请等待 <code>avatar-image-loaded</code> 回调，然后再次调用。</p>
</div>
</div>
<div class="sect3">
<h4 id="_设置监听好友消息">6.3.7. 设置监听好友消息</h4>
<div class="paragraph">
<p><strong>greenworks.setListenForFriendsMessage(intecept_enabled)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>intercept_enabled</code> Boolean 启用（true）或关闭（(false）拦截好友消息？</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>设置监听 Steam 好友的聊天消息事件 (<code>game-connected-friend-chat-message</code>)。 返回一个 <code>Boolean</code>，表示是否成功设置了侦听器。</p>
</div>
</div>
<div class="sect3">
<h4 id="_回复好友消息">6.3.8. 回复好友消息</h4>
<div class="paragraph">
<p><strong>greenworks.replyToFriendMessage(raw_steam_id, message)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 要发送消息至的好友的 Steam ID。</p>
</li>
<li>
<p><code>message</code> String: 待发送的 UTF-8 格式消息。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>给 Steam 好友发送一则消息。 返回一个 <code>Boolean</code>，表示消息是否成功发送。</p>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友消息">6.3.9. 获取好友消息</h4>
<div class="paragraph">
<p><strong>greenworks.getFriendMessage(raw_steam_id, message_id, maximum_message_size)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 发出该消息的好友的 Steam ID。</p>
</li>
<li>
<p><code>message_id</code> Integer 消息的索引。 应为 GameConnectedFriendChatMsg_t 的 m_iMessageID 字段。</p>
</li>
<li>
<p><code>maximum_message_size</code> Integer 缓冲区接收的最大消息大小</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>String</code>，表示来自朋友的消息。</p>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友姓名显示名称">6.3.10. 获取好友姓名（显示名称）</h4>
<div class="paragraph">
<p><strong>greenworks.getFriendPersonaName(raw_steam_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>raw_steam_id</code> String: 另一位用户的 Steam ID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回表示指定用户个人（显示）姓名的 <code>String</code>。</p>
</div>
</div>
<div class="sect3">
<h4 id="_设置当前用户的丰富状态键值">6.3.11. 设置当前用户的丰富状态键/值</h4>
<div class="paragraph">
<p><strong>greenworks.setRichPresence(pchKey, pchValue)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>pchKey</code> String: 要设置的丰富状态 'key'。 不可比 <a href="https://partner.steamgames.com/doc/api/ISteamFriends#k_cchMaxRichPresenceKeyLength">k_cchMaxRichPresenceKeyLength</a> 中指定的长。</p>
</li>
<li>
<p><code>pchValue</code> String: 要与 <code>pchKey</code> 关联的丰富状态 'value'。 不可比 <a href="https://partner.steamgames.com/doc/api/ISteamFriends#k_cchMaxRichPresenceValueLength">k_cchMaxRichPresenceValueLength</a> 中规定的长。 若设为空字符串（""）或 NULL，便会移除已设置的键。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值:</p>
</div>
<div class="paragraph">
<p><code>true</code> 表示丰富状态设置成功。
<code>false</code> 有下面这些情况:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>pchKey</code> 超过了 <code>k_cchMaxRichPresenceKeyLength</code> 中规定的大小，或者长度为 0</p>
</li>
<li>
<p><code>pchValue</code> 超过了 <code>k_cchMaxRichPresenceValueLength</code> 中规定的大小。</p>
</li>
<li>
<p>用户已经达到了 <a href="https://partner.steamgames.com/doc/api/ISteamFriends#k_cchMaxRichPresenceKeys">k_cchMaxRichPresenceKeys</a> 指定的丰富状态键的最大数量。</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_清除丰富状态">6.3.12. 清除丰富状态</h4>
<div class="paragraph">
<p><strong>greenworks.ClearRichPresence()</strong></p>
</div>
<div class="paragraph">
<p>清除当前用户所有的丰富状态（Rich Presence）键/值。</p>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友的丰富状态">6.3.13. 获取好友的丰富状态</h4>
<div class="paragraph">
<p><strong>greenworks.getFriendRichPresence(steamIDFriend, pchKey)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDFriend</code> String: 要获取其 Rich Presence 值的好友。</p>
</li>
<li>
<p><code>pchKey</code> String: 要请求的 Rich Presence 键。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>String</code> 值，表示指定好友的丰富状态</p>
</div>
</div>
<div class="sect3">
<h4 id="SetPlayedWith">6.3.14. 设置和谁一起玩过</h4>
<div class="paragraph">
<p><strong>greenworks.setPlayedWith(steamIDUserPlayedWith)</strong></p>
</div>
<div class="paragraph">
<p>将目标用户标记为“一起玩过游戏的”。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDUserPlayedWith</code> String: 一起玩过游戏的另一位用户。</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_获取好友正在玩的游戏">6.3.15. 获取好友正在玩的游戏</h4>
<div class="paragraph">
<p><strong>greenworks.getFriendGamePlayed(steamIDFriend)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>steamIDFriend</strong> String: 另一位用户的 Steam ID</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>如果好友在游戏中，则会返回一个 <a href="https://partner.steamgames.com/doc/api/ISteamFriends#FriendGameInfo_t">FriendGameInfo_t</a> 对象，否则会返回 <code>undefined</code> 。</p>
</div>
</div>
<div class="sect3">
<h4 id="_激活邀请游戏对话框">6.3.16. 激活邀请游戏对话框</h4>
<div class="paragraph">
<p><strong>greenworks.activateGameOverlayInviteDialog(steamIDLobby)</strong></p>
</div>
<div class="paragraph">
<p>激活 Steam 界面，打开邀请对话框。 从此窗口发出进入该大厅的邀请。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>steamIDLobby</strong> String: 选定玩家将受邀进入的大厅的 Steam ID。</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_打开特定用户的对话框">6.3.17. 打开特定用户的对话框</h4>
<div class="paragraph">
<p><strong>greenworks.activateGameOverlayToUser(pchDialog, CSteamID steamID)</strong></p>
</div>
<div class="paragraph">
<p>激活 Steam 界面，打开指定的对话框</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>pchDialog</code> String:要打开的对话框</p>
</li>
<li>
<p><code>steamID</code> String: 要将此对话框打开至的上下文的 Steam ID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>pchDialog有下面这些有效选项:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>"steamid" - 打开界面网页浏览器，前往指定的用户或组资料。</p>
</li>
<li>
<p>"chat" - 打开与指定用户的聊天窗口，或加入组聊天。</p>
</li>
<li>
<p>"jointrade" - 打开以 <a href="https://partner.steamgames.com/doc/webapi/ISteamEconomy#StartTrade">ISteamEconomy/StartTrade</a> Web API 开始的 Steam 交易会话窗口。</p>
</li>
<li>
<p>"stats" - 打开界面网页浏览器，前往指定用户的统计。</p>
</li>
<li>
<p>"achievements" - 打开界面网页浏览器，前往指定用户的成就。</p>
</li>
<li>
<p>"friendadd" - 以最小模式打开界面，提示用户将目标用户加为好友。</p>
</li>
<li>
<p>"friendremove" - 以最小模式打开界面，提示用户移除目标好友。</p>
</li>
<li>
<p>"friendrequestaccept" - 以最小模式打开界面，提示用户接受传入的好友邀请。</p>
</li>
<li>
<p>"friendrequestignore" - 以最小模式打开界面，提示用户忽略传入的好友邀请。</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_环境设置">7. 环境设置</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_初始化_steamworks_api">7.1. 初始化 Steamworks API</h3>
<div class="paragraph">
<p><strong>greenworks.initAPI()</strong></p>
</div>
<div class="paragraph">
<p>返回 <code>Boolean</code> ，表示是否成功初始化Steam API。</p>
</div>
<div class="paragraph">
<p>注意：测试时，您需要启动并登录Steam客户端，并在应用程序目录下创建一个带有Steam APP ID（或steamworks示例APP ID）的Steam_appid.txt文件。</p>
</div>
</div>
<div class="sect2">
<h3 id="_初始化">7.2. 初始化</h3>
<div class="paragraph">
<p><strong>greenworks.init()</strong></p>
</div>
<div class="paragraph">
<p>当成功初始化Steam API时，返回 <code>True</code>，否则会抛出一个异常。</p>
</div>
</div>
<div class="sect2">
<h3 id="_判断steam是否正在运行">7.3. 判断steam是否正在运行</h3>
<div class="paragraph">
<p><strong>greenworks.isSteamRunning()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示steam是否在运行中。</p>
</div>
</div>
<div class="sect2">
<h3 id="_在需要的时候重启应用">7.4. 在需要的时候重启应用</h3>
<div class="paragraph">
<p><strong>greenworks.restartAppIfNecessary(appId)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>appId</code> Integer: 游戏的APP ID</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>如果你的应用程序不是通过Steam启动的，这将向Steam发出启动应用程序的信号，然后导致你的应用退出。 调用 <code>restartAppIfNecessary()</code> 后，您不会有任何损失，但如果它返回 <code>true</code> ，则您的应用程序正在重新启动。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取游戏id">7.5. 获取游戏ID</h3>
<div class="paragraph">
<p><strong>greenworks.getAppId()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 值，表示当前运行中的游戏id。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取游戏构建id">7.6. 获取游戏构建ID</h3>
<div class="paragraph">
<p><strong>greenworks.getAppBuildId()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 值，表示游戏的构建id。 可能会根据游戏后台的更新而随时发生变化。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取steamid对象">7.7. 获取SteamId对象</h3>
<div class="paragraph">
<p><strong>greenworks.getSteamId()</strong></p>
</div>
<div class="paragraph">
<p>返回一个表示当前用户的 <a href="https://github.com/greenheartgames/greenworks/blob/master/docs/friends.md#steamid">SteamID</a> 的对象。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取当前游戏语言">7.8. 获取当前游戏语言</h3>
<div class="paragraph">
<p><strong>greenworks.getCurrentGameLanguage()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 值，表示Steam中专门为该游戏设置的当前语言。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取当前ui的语言">7.9. 获取当前UI的语言</h3>
<div class="paragraph">
<p><strong>greenworks.getCurrentUILanguage()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>String</code> 值，表示Steam UI中设置的当前语言。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取当前游戏安装目录">7.10. 获取当前游戏安装目录</h3>
<div class="paragraph">
<p><strong>greenworks.getCurrentGameInstallDir()</strong></p>
</div>
<div class="paragraph">
<p>尚未实现.</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取应用安装目录">7.11. 获取应用安装目录</h3>
<div class="paragraph">
<p><strong>greenworks.getAppInstallDir(app_id, buffer, buffer_size)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>app_id</strong> Integer: 游戏的APP ID</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>String</code> 值，表示应用安装目录的绝对路径。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取玩家数量">7.12. 获取玩家数量</h3>
<div class="paragraph">
<p><strong>greenworks.getNumberOfPlayers(success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>success_callback</code> Function(num_of_players)</p>
<div class="ulist">
<ul>
<li>
<p><code>num_of_players</code> Integer: Steam上当前游戏的玩家数量。</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_打开steam遮罩层">7.13. 打开Steam遮罩层</h3>
<div class="paragraph">
<p><strong>greenworks.activateGameOverlay(option)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>option</code> String: 有效的选项宝坤 <code>Friends</code>, <code>Community</code>, <code>Players</code>, <code>Settings</code>, <code>OfficialGameGroup</code>, <code>Stats</code> 和 <code>Achievements</code>。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>激活 <code>option</code> 指定的游戏遮罩层。</p>
</div>
</div>
<div class="sect2">
<h3 id="_是否启用steam遮罩层">7.14. 是否启用Steam遮罩层</h3>
<div class="paragraph">
<p><strong>greenworks.isGameOverlayEnabled()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示Steam遮罩层是否被启用或禁用。</p>
</div>
</div>
<div class="sect2">
<h3 id="_判断steam是否处于大屏幕模式">7.15. 判断Steam是否处于大屏幕模式</h3>
<div class="paragraph">
<p><strong>greenworks.isSteamInBigPictureMode()</strong></p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示Steam是否处于大屏幕模式。如果应用程序不在Steam的 <code>游戏</code> 类别中，则始终返回 <code>false</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_通过steam遮罩层打开web页面">7.16. 通过Steam遮罩层打开Web页面</h3>
<div class="paragraph">
<p><strong>greenworks.activateGameOverlayToWebPage(url)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>url</code> String: 完整的url，例如。http://www.steamgames.com.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>在steam游戏遮罩层中打开指定的url。</p>
</div>
</div>
<div class="sect2">
<h3 id="_判断是否购买了游戏">7.17. 判断是否购买了游戏</h3>
<div class="paragraph">
<p><strong>greenworks.isSubscribedApp(appId)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>appId</code> Integer: 游戏的APP ID</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code>，表示用户是否购买了游戏。</p>
</div>
</div>
<div class="sect2">
<h3 id="_判断应用是否已安装">7.18. 判断应用是否已安装</h3>
<div class="paragraph">
<p><strong>greenworks.isAppInstalled(appId)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>appId</code> Integer: 应用的APP ID</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code>，表示应用是否已安装。该应用实际上可能不属于用户。</p>
</div>
<div class="paragraph">
<p>仅适用于应用本体，DLC使用的是 <code>isDLCInstalled</code> 。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取图片大小">7.19. 获取图片大小</h3>
<div class="paragraph">
<p><strong>greenworks.getImageSize(handle)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>handle</code> Integer: 要获取大小的图像句柄。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>对象</code>，包含图片的宽高值。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取图像字节">7.20. 获取图像字节</h3>
<div class="paragraph">
<p><strong>greenworks.getImageRGBA(handle)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>handle</code> Integer: 图片句柄</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Buffer</code> ，表示RGBA格式的图片数据。</p>
</div>
<div class="paragraph">
<p>下面是保存 <code>png</code> 格式图片的示例：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">var greeenworks = require('./greenworks');
// Relies on 'jimp' module. Install it via 'npm install jimp'.
var Jimp = require('jimp');

var friends = greenworks.getFriends(greenworks.FriendFlags.Immediate);
if (friends.length &gt; 0) {
  var handle = greenworks.getSmallFriendAvatar(friends[0].getRawSteamID());
  if (!handle) {
    console.log("The user don't set small avartar");
    return;
  }
  var image_buffer = greenworks.getImageRGBA(handle);
  var size = greenworks.getImageSize(handle);
  if (!size.height || !size.width) {
    console.log("Image corrupted. Please try again");
    return;
  }
  console.log(size);
  var image = new Jimp(size.height, size.width, function (err, image) {
    for (var i = 0; i &lt; size.height; ++i) {
      for (var j = 0; j &lt; size.width; ++j) {
        var idx = 4 * (i * size.height + j);
        var hex = Jimp.rgbaToInt(image_buffer[idx], image_buffer[idx+1],
            image_buffer[idx+2], image_buffer[idx+3]);
        image.setPixelColor(hex, j, i);
      }
    }
  });
  image.write("/tmp/test.png");
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_获取ip所在国家">7.21. 获取IP所在国家</h3>
<div class="paragraph">
<p><strong>greenworks.getIPCountry()</strong></p>
</div>
<div class="paragraph">
<p>返回客户端正在运行的 2 位 ISO 3166-1-alpha-2 格式的国家代码。 如“US”或“UK”。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取启动命令行">7.22. 获取启动命令行</h3>
<div class="paragraph">
<p><strong>greenworks.getLaunchCommandLine()</strong></p>
</div>
<div class="paragraph">
<p>如果游戏通过 Steam URL 如 <code>steam://run/&lt;appid&gt;//&lt;command line&gt;/</code> 启动，则可以获取启动命令行。 此方法优于通过操作系统用命令行启动，后者可能存在安全隐患。 为了使丰富状态加入能使用此方式，而不被置于操作系统命令行，您必须在您应用的“安装”&gt;“通用安装”页面上启用“使用启动命令行”。</p>
</div>
<div class="paragraph">
<p><a href="https://partner.steamgames.com/doc/api/ISteamApps#GetLaunchCommandLine">Steam docs</a></p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_统计">8. 统计</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_获取用户的统计值">8.1. 获取用户的统计值</h3>
<div class="paragraph">
<p><strong>greenworks.getStatInt(name)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>name</code> String: 用户统计的API 名称</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 值，表示用户的统计状态值。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取用户的float格式统计值">8.2. 获取用户的float格式统计值</h3>
<div class="paragraph">
<p><strong>greenworks.getStatFloat(name)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>name</code> String: 用户统计的API 名称</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Float</code> 值，表示用户的统计值。</p>
</div>
</div>
<div class="sect2">
<h3 id="setStat">8.3. 设置/更新指定统计值</h3>
<div class="paragraph">
<p><strong>greenworks.setStat(name, value)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>name</code> String: 用户统计的API 名称</p>
</li>
<li>
<p><code>value</code> Integer or Float: 用户的统计值</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示方法调用是否成功。</p>
</div>
</div>
<div class="sect2">
<h3 id="_持久保存统计值">8.4. 持久保存统计值</h3>
<div class="paragraph">
<p><strong>greenworks.storeStats(success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>success_callback</code> Function(game_id)</p>
<div class="ulist">
<ul>
<li>
<p><code>game_id</code>: 这些统计数据用于哪个游戏</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将变动的统计与成就数据发送至服务器进行持久保存。</p>
</div>
</div>
<div class="sect2">
<h3 id="_重置所有统计状态">8.5. 重置所有统计状态</h3>
<div class="paragraph">
<p>greenworks.resetAllStats(isResetAchievement)</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>isResetAchievement</code> Boolean: 是否重置成就</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>重置当前用户的统计状态。</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_工具方法">9. 工具方法</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_移动文件夹">9.1. 移动文件夹</h3>
<div class="paragraph">
<p><strong>greenworks.Utils.move(source_dir, target_dir, [success_callback], [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>source_dir</code> String</p>
</li>
<li>
<p><code>target_dir</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将 <code>source_dir</code> 源目录移动到 <code>target_dir</code> 目标目录。</p>
</div>
</div>
<div class="sect2">
<h3 id="_创建压缩包">9.2. 创建压缩包</h3>
<div class="paragraph">
<p><strong>greenworks.Utils.createArchive(zip_file_path, source_dir, password, compress_level, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>zip_file_path</code> String</p>
</li>
<li>
<p><code>source_dir</code> String</p>
</li>
<li>
<p><code>password</code> String: 字符串表示没有密码</p>
</li>
<li>
<p><code>compress_level</code> Integer: 压缩系数0-9，数值越大压缩率越大</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将 <code>source_dir</code> 源目录打包成一个ZIP压缩包文件。</p>
</div>
</div>
<div class="sect2">
<h3 id="_解压压缩包">9.3. 解压压缩包</h3>
<div class="paragraph">
<p><strong>greenworks.Utils.extractArchive(zip_file_path, extract_dir, password, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>zip_file_path</code> String</p>
</li>
<li>
<p><code>extract_dir</code> String</p>
</li>
<li>
<p><code>password</code> String: 空字符串表示没有密码</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将压缩文件 <code>zip_file_path</code> 解压缩到指定的 <code>extract_dir</code> 目录。</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_创意工坊">10. 创意工坊</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_ugcmatchingtype">10.1. UGCMatchingType</h3>
<div class="paragraph">
<p><strong>greenworks.UGCMatchingType</strong></p>
</div>
<div class="paragraph">
<p>Represents Steam SDK <code>EUGCMatchingUGCType</code>, matching UGC types for queries.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Items</code></p>
</li>
<li>
<p><code>ItemsMtx</code></p>
</li>
<li>
<p><code>ItemsReadyToUse</code></p>
</li>
<li>
<p><code>Collections</code></p>
</li>
<li>
<p><code>Artwork</code></p>
</li>
<li>
<p><code>Videos</code></p>
</li>
<li>
<p><code>Screenshots</code></p>
</li>
<li>
<p><code>AllGuides</code></p>
</li>
<li>
<p><code>WebGuides</code></p>
</li>
<li>
<p><code>IntegratedGuides</code></p>
</li>
<li>
<p><code>UsableInGame</code></p>
</li>
<li>
<p><code>ControllerBindings</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_ugcquerytype">10.2. UGCQueryType</h3>
<div class="paragraph">
<p><strong>greenworks.UGCQueryType</strong></p>
</div>
<div class="paragraph">
<p>Represents Steam SDK <code>EUGCQuery</code>, combination of sorting and filtering for queries across all UGC.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>RankedByVote</code></p>
</li>
<li>
<p><code>RankedByPublicationDate</code></p>
</li>
<li>
<p><code>AcceptedForGameRankedByAcceptanceDate</code></p>
</li>
<li>
<p><code>RankedByTrend</code></p>
</li>
<li>
<p><code>FavoritedByFriendsRankedByPublicationDate</code></p>
</li>
<li>
<p><code>CreatedByFriendsRankedByPublicationDate</code></p>
</li>
<li>
<p><code>RankedByNumTimesReported</code></p>
</li>
<li>
<p><code>CreatedByFollowedUsersRankedByPublicationDate</code></p>
</li>
<li>
<p><code>NotYetRated</code></p>
</li>
<li>
<p><code>RankedByTotalVotesAsc</code></p>
</li>
<li>
<p><code>RankedByVotesUp</code></p>
</li>
<li>
<p><code>RankedByTextSearch</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_steamugcdetails">10.3. SteamUGCDetails</h3>
<div class="paragraph">
<p>Represents Steam SDK <code>SteamUGCDetails_t</code>(return by <code>greenworks.ugcGetItems</code>), details for a single published file/UGC</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>acceptForUse</code> Boolean: Whether is flaged as accepted in Steam workshop.</p>
</li>
<li>
<p><code>banned</code> Boolean: Whether is banned</p>
</li>
<li>
<p><code>tagsTruncated</code> Boolean: Whether the list of tags is too long to be returned in provided buffer.</p>
</li>
<li>
<p><code>fileType</code> Integer: Type of the file</p>
</li>
<li>
<p><code>result</code> Integer: Result of the operation.</p>
<div class="ulist">
<ul>
<li>
<p><code>1</code>: Success</p>
</li>
<li>
<p><code>Others</code>: Fail</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>visibility</code> Integer: the visiblility of the file</p>
<div class="ulist">
<ul>
<li>
<p><code>0</code>: Public</p>
</li>
<li>
<p><code>1</code>: FriendsOnly</p>
</li>
<li>
<p><code>2</code>: Private</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>score</code> Double: Calculated score</p>
</li>
<li>
<p><code>file</code> String: Represents uint64, file handle</p>
</li>
<li>
<p><code>fileName</code> String: Cloud file name of the primary file</p>
</li>
<li>
<p><code>fileSize</code> Integer: Size of the primary file</p>
</li>
<li>
<p><code>previewFile</code> String: Represents uint64, handle of preview file</p>
</li>
<li>
<p><code>previewFileSize</code> Integer: Size of preview file</p>
</li>
<li>
<p><code>steamIDOwner</code> String: Represents uint64, Steam ID of user who created the file.</p>
</li>
<li>
<p><code>consumerAppID</code> Integer: ID of app that consumes the file</p>
</li>
<li>
<p><code>creatorAppID</code> Integer: ID of app that created the file</p>
</li>
<li>
<p><code>publishedFileId</code> String: Represents uint64, the file ID</p>
</li>
<li>
<p><code>title</code> String: Title of the file</p>
</li>
<li>
<p><code>description</code> String: Description of the file</p>
</li>
<li>
<p><code>URL</code> String:</p>
</li>
<li>
<p><code>tags</code> String: List of tags, separated by comma.</p>
</li>
<li>
<p><code>timeAddedToUserList</code> Integer: Time when user added this file to list.</p>
</li>
<li>
<p><code>timeCreated</code> Integer: Time when the file was created</p>
</li>
<li>
<p><code>timeUpdated</code> Integer: Time when the file is last updated.</p>
</li>
<li>
<p><code>votesDown</code> Integer: Number of votes down</p>
</li>
<li>
<p><code>votesUp</code> Integer: Number of votes up</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_userugclist">10.4. UserUGCList</h3>
<div class="paragraph">
<p><strong>greenworks.UserUGCList</strong></p>
</div>
<div class="paragraph">
<p>Represents Steam SDK <code>EUserUGCList</code>, different lists of published UGC for a user.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Published</code></p>
</li>
<li>
<p><code>VotedOn</code></p>
</li>
<li>
<p><code>VotedUp</code></p>
</li>
<li>
<p><code>VotedDown</code></p>
</li>
<li>
<p><code>WillVoteLater</code></p>
</li>
<li>
<p><code>Favorited</code></p>
</li>
<li>
<p><code>Subscribed</code></p>
</li>
<li>
<p><code>UsedOrPlayer</code></p>
</li>
<li>
<p><code>Followed</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_userugclistsortorder">10.5. UserUGCListSortOrder</h3>
<div class="paragraph">
<p><strong>greenworks.UserUGCListSortOrder</strong></p>
</div>
<div class="paragraph">
<p>Represents Steam SDK <code>EUserUGCListSortOrder</code>, sort order for user published UGC lists</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CreationOrderDesc</code></p>
</li>
<li>
<p><code>CreationOrderAsc</code></p>
</li>
<li>
<p><code>TitleAsc</code></p>
</li>
<li>
<p><code>LastUpdatedDesc</code></p>
</li>
<li>
<p><code>SubscriptionDateDesc</code></p>
</li>
<li>
<p><code>VoteScoreDesc</code></p>
</li>
<li>
<p><code>ForModeration</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_ugcitemstate">10.6. UGCItemState</h3>
<div class="paragraph">
<p><strong>greenworks.UGCItemState</strong></p>
</div>
<div class="paragraph">
<p>Represents Steam SDK <code>EItemState</code>, local state of a workshop item (combinable flags)</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>None</code></p>
</li>
<li>
<p><code>Subscribed</code></p>
</li>
<li>
<p><code>LegacyItem</code></p>
</li>
<li>
<p><code>Installed</code></p>
</li>
<li>
<p><code>NeedsUpdate</code></p>
</li>
<li>
<p><code>Downloading</code></p>
</li>
<li>
<p><code>DownloadPending</code></p>
</li>
<li>
<p><code>Methods</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_共享文件">10.7. 共享文件</h3>
<div class="paragraph">
<p><strong>greenworks.fileShare(file_path, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>file_path</code> String</p>
</li>
<li>
<p><code>success_calback</code> Function(file_handle)</p>
<div class="ulist">
<ul>
<li>
<p><code>file_handle</code> String: 表示可以与用户和功能共享的文件句柄。</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_发布工坊文件">10.8. 发布工坊文件</h3>
<div class="paragraph">
<p><strong>greenworks.publishWorkshopFile([options, ] file_path, image_path, title, description, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>options</code> Object</p>
<div class="ulist">
<ul>
<li>
<p><code>app_id</code> Integer: 将使用此工坊文件的游戏ID</p>
</li>
<li>
<p><code>tags</code> Array of String: 工坊文件的标签</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>file_path</code> String</p>
</li>
<li>
<p><code>image_path</code> String</p>
</li>
<li>
<p><code>title</code> String</p>
</li>
<li>
<p><code>description</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function(publish_file_handle)</p>
<div class="ulist">
<ul>
<li>
<p><code>publish_file_handle</code> String: Represents uint64, the published file handle</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将 file_path 路径的文件发布到steam。 在这么做之前，<code>file_path</code> 和 <code>image_path</code> 路径下的文件需要存在于SteamCloud上（使用 <code>writeTextToFile</code> 或者是 <code>saveFilesToCloud</code> API）并且需要共享（使用 <code>Greenworks.fileShare</code> API）。</p>
</div>
<div class="paragraph">
<p><code>image_path</code> 参数是空字符串的话则表示不向工坊发送图片文件。</p>
</div>
</div>
<div class="sect2">
<h3 id="_更新已发布的工坊文件">10.9. 更新已发布的工坊文件</h3>
<div class="paragraph">
<p><strong>greenworks.updatePublishedWorkshopFile([options, ] published_file_handle, file_path, image_path, title, description, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>options</code> Object</p>
<div class="ulist">
<ul>
<li>
<p><code>tags</code> Array of String: 工坊文件的标签。若要删除所有现有标记，请传递带有空字符串 <code>['']</code> 的数组</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>published_file_handle</code> String: 发布的文件句柄</p>
</li>
<li>
<p><code>file_path</code> String</p>
</li>
<li>
<p><code>image_path</code> String</p>
</li>
<li>
<p><code>title</code> String</p>
</li>
<li>
<p><code>description</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><code>file_path</code>/<code>image_path</code>/<code>title</code>/<code>description</code> 这些字段如果是空字符串则代表不更新对应字段。</p>
</div>
</div>
<div class="sect2">
<h3 id="_发布到工坊">10.10. 发布到工坊</h3>
<div class="paragraph">
<p><strong>greenworks.ugcPublish(file_path, title, description, image_path, success_callback, [error_callback], [progress_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>file_path</code> String</p>
</li>
<li>
<p><code>title</code> String</p>
</li>
<li>
<p><code>description</code> String</p>
</li>
<li>
<p><code>image_path</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function(published_file_handle)</p>
<div class="ulist">
<ul>
<li>
<p><code>published_file_handle</code> String: 发布的文件句柄</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
<li>
<p><code>progress_callback</code> Function(progress_msg)</p>
<div class="ulist">
<ul>
<li>
<p><code>progress_msg</code> String: 发布过程的当前进度： <code>文件保存到Steam Cloud完成</code>，<code>文件共享完成</code>。</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>将用户生成的内容发布到Steam工坊，</p>
</div>
</div>
<div class="sect2">
<h3 id="_发布更新">10.11. 发布更新</h3>
<div class="paragraph">
<p><strong>greenworks.ugcPublishUpdate(published_file_handle, file_path, title, description, image_path, success_callback, [error_callback], [progress_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>published_file_handle</code> String: 发布的文件句柄</p>
</li>
<li>
<p><code>file_path</code> String</p>
</li>
<li>
<p><code>title</code> String</p>
</li>
<li>
<p><code>description</code> String</p>
</li>
<li>
<p><code>image_path</code> String</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
<li>
<p><code>progress_callback</code> Function(progress_msg)</p>
</li>
<li>
<p><code>progress_msg</code> String: 发布过程的当前进度： <code>文件保存到Steam Cloud完成</code>，<code>文件共享完成</code>。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>更新已发布的工坊文件。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取所有文件">10.12. 获取所有文件</h3>
<div class="paragraph">
<p><strong>greenworks.ugcGetItems([options, ] ugc_matching_type, ugc_query_type, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>options</code> Object</p>
<div class="ulist">
<ul>
<li>
<p><code>app_id</code> Integer: 将使用此工坊文件的游戏ID</p>
</li>
<li>
<p><code>page_num</code> Integer: 要接收结果的页码，第一次调用时应从1开始，每页最大50条数据</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>ugc_matching_type</code> greenworks.UGCMatchingType</p>
</li>
<li>
<p><code>ugc_query_type</code> greenworks.UGCQueryType</p>
</li>
<li>
<p><code>success_callback</code> Function(items)</p>
<div class="ulist">
<ul>
<li>
<p><code>items</code>  <code>SteamUGCDetails</code> 创意工坊文件详细信息对象数组</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_获取用户文件">10.13. 获取用户文件</h3>
<div class="paragraph">
<p><strong>greenworks.ugcGetUserItems([options, ] ugc_matching_type, ugc_list_sort_order, ugc_list, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>options</code> Object</p>
<div class="ulist">
<ul>
<li>
<p><code>app_id</code> Integer: 将使用此工坊文件的游戏ID</p>
</li>
<li>
<p><code>page_num</code> Integer: 要接收结果的页码，第一次调用时应从1开始，每页最大50条数据</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>ugc_matching_type</code> greenworks.UGCMatchingType</p>
</li>
<li>
<p><code>ugc_list_sort_order</code> greenworks.UserUGCListSortOrder</p>
</li>
<li>
<p><code>ugc_list</code> greenworks.UserUGCList</p>
</li>
<li>
<p><code>success_callback</code> Function(items)</p>
<div class="ulist">
<ul>
<li>
<p><code>items</code> <code>SteamUGCDetails</code> 创意工坊文件详细信息对象数组</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_下载文件">10.14. 下载文件</h3>
<div class="paragraph">
<p><strong>greenworks.ugcDownloadItem(download_file_handle, download_dir, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>download_file_handle</code> String: 要下载的文件句柄</p>
</li>
<li>
<p><code>download_dir</code> String: 在本地计算机上保存下载文件的文件路径</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_同步文件">10.15. 同步文件</h3>
<div class="paragraph">
<p><strong>greenworks.ugcSynchronizeItems([options, ] sync_dir, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>options</code> Object</p>
<div class="ulist">
<ul>
<li>
<p><code>app_id</code> Integer: 将使用此工坊文件的游戏ID</p>
</li>
<li>
<p><code>page_num</code> Integer: 要接收结果的页码，第一次调用时应从1开始，每页最大50条数据</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>sync_dir</code> String: 下载同步工坊文件的目录。</p>
</li>
<li>
<p><code>success_callback</code> Function(items)</p>
<div class="ulist">
<ul>
<li>
<p><code>items</code> <code>SteamUGCDetails</code> 创意工坊文件详细信息对象数组</p>
</li>
<li>
<p><code>isUpdated</code> Boolean: 是否在此函数调用的过程中更新文件</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>将用户的工坊文件 (<code>UserUGCList.Subscribed</code>, <code>UserMatchingType.Items</code>) 下载/同步到本地的 <code>sync_dir</code> 目录（仅当文件的上次更新时间与Steam Cloud不同或本地不存在工坊文件时才更新）。</p>
</div>
</div>
<div class="sect2">
<h3 id="_取消订阅">10.16. 取消订阅</h3>
<div class="paragraph">
<p><strong>greenworks.ugcUnsubscribe(published_file_handle, success_callback, [error_callback])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>published_file_handle</code> String: 想要取消订阅的文件句柄(SteamUGCDetails.publishedFileId).</p>
</li>
<li>
<p><code>success_callback</code> Function()</p>
</li>
<li>
<p><code>error_callback</code> Function(err)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_显示工坊对话框">10.17. 显示工坊对话框</h3>
<div class="paragraph">
<p><strong>greenworks.ugcShowOverlay([published_file_id])</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>published_file_id</code> String: 已发布文件的id</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>显示Steam工坊页面或指定工坊文件的Steam对话框。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取文件状态">10.18. 获取文件状态</h3>
<div class="paragraph">
<p><strong>greenworks.ugcGetItemState(published_file_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>published_file_id</code> String: 已发布文件的id</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>拉取指定工坊文件的 <code>greenworks.UGCItemState</code> 值。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取文件安装信息">10.19. 获取文件安装信息</h3>
<div class="paragraph">
<p><strong>greenworks.ugcGetItemInstallInfo(published_file_id)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>published_file_id</code> String: 已发布文件的id</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>如果工坊文件的状态包括 <code>greenworks.UGCItemState.Installed</code>，则拉取工坊文件的安装信息。 如果无法获取信息，则返回 <code>undefined</code> ；否则返回包含以下属性的 <code>对象</code>：</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>sizeOnDisk</code> String: 返回创意工坊物品的字节大小</p>
</li>
<li>
<p><code>folder</code> String: 硬盘上项目文件夹的绝对路径，如果状态为 <code>LegacyItem</code> 则指向文件本身</p>
</li>
<li>
<p><code>timestamp</code> Integer:返回工坊文件的上次更新的时间</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_匹配大厅">11. 匹配大厅</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="LobbyType">11.1. 大厅类型对象</h3>
<div class="paragraph">
<p><strong>greenworks.LobbyType</strong></p>
</div>
<div class="paragraph">
<p>大厅类型，从 CreateLobby 或 SetLobbyType 设置。</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>Private</code> (0.只能通过邀请加入大厅)</p>
</li>
<li>
<p><code>FriendsOnly</code> (1.好友和受邀者可加入，但不出现在大厅列表中)</p>
</li>
<li>
<p><code>Public</code> (2.可以通过搜索返回并对好友可见)</p>
</li>
<li>
<p><code>Invisible</code> (3.通过搜索返回，但不对好友可见。如果希望一个用户同时在两个大厅中，比如将组配到一起时很有用。 用户只能加入一个普通大厅，最多可加入两个不可见大厅。)</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_创建匹配大厅">11.2. 创建匹配大厅</h3>
<div class="paragraph">
<p><strong>createLobby(lobbyType, maxMembers)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>lobbyType</code> <a href="#LobbyType">greenworks.LobbyType</a></p>
</li>
<li>
<p><code>maxMembers</code> Integer: 可加入此大厅的玩家最大数量。 不能超过 250 人</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>创建一个新的匹配大厅。</p>
</div>
<div class="paragraph">
<p>返回一个指向 Steam API 调用的唯一 <code>String</code> 型句柄。</p>
</div>
</div>
<div class="sect2">
<h3 id="_设置大厅数据">11.3. 设置大厅数据</h3>
<div class="paragraph">
<p><strong>setLobbyData(steamIDLobby, pchKey, pchValue)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要设置元数据的大厅 Steam ID。可以在lobby-created回调函数中获得</p>
</li>
<li>
<p><code>pchKey</code> String: 要设置数据的键。 不得长于255</p>
</li>
<li>
<p><code>pchValue</code> String: 要设置的值。 不得长于8192</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>在大厅元数据中设置键/值对。 此函数可用于设置大厅名称、当前地图、游戏模式等。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值表示是否设置成功。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取大厅数据">11.4. 获取大厅数据</h3>
<div class="paragraph">
<p><strong>getLobbyData(steamIDLobby, pchKey)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要从中获得元数据的大厅的 Steam ID</p>
</li>
<li>
<p><code>pchKey</code> String: 要获取值的键</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获取与指定大厅中的指定键相关的元数据。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>String</code> 字符串表示取到的值。如果没有为此键设置值，或 steamIDLobby 无效，则返回一个空白字符串（""）。</p>
</div>
</div>
<div class="sect2">
<h3 id="_删除大厅数据">11.5. 删除大厅数据</h3>
<div class="paragraph">
<p><strong>deleteLobbyData(steamIDLobby, pchKey)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 待删除元数据的大厅的 Steam ID。</p>
</li>
<li>
<p><code>pchKey</code> String: 待删除数据的键。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>从大厅移除元数据键。 此操作只能由大厅所有者完成。 只有当键存在时，才会发送数据。 在发送数据之前会稍有延迟，因此您可以重复调用来设置您需要的所有数据，并在最后一次顺序调用之后，数据将被自动批处理和发送。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 。true， 表示成功删除了键/值；否则，如果 steamIDLobby 或 pchKey 无效，则为 false。</p>
</div>
</div>
<div class="sect2">
<h3 id="_加入匹配大厅">11.6. 加入匹配大厅</h3>
<div class="paragraph">
<p><strong>joinLobby(steamIDLobby)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要加入的大厅的 Steam ID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>加入一个现有大厅。 可以用 RequestLobbyList 搜索并加入好友从而获取大厅的 Steam ID，也可以从邀请中获取。</p>
</div>
<div class="paragraph">
<p>返回指向一个 Steam API 调用的唯一 <code>String</code> 句柄。</p>
</div>
</div>
<div class="sect2">
<h3 id="_退出匹配大厅">11.7. 退出匹配大厅</h3>
<div class="paragraph">
<p><strong>leaveLobby(steamIDLobby)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要离开的大厅id。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>离开用户当前所在的大厅，这将立即在客户端生效，大厅的其他用户将得到 LobbyChatUpdate_t 回调的通知。</p>
</div>
</div>
<div class="sect2">
<h3 id="_根据索引获得大厅信息">11.8. 根据索引获得大厅信息</h3>
<div class="paragraph">
<p><strong>getLobbyByIndex(index)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>index</code> Integer: 要获得其 Steam ID 的大厅索引，从 0 至 LobbyMatchList_t.m_nLobbiesMatching。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>收到 RequestLobbyList 结果后，获得指定索引中大厅的 Steam ID。</p>
</div>
<div class="paragraph">
<p>返回一个 <a href="#SteamID">SteamID</a> 对象；如果所提供的索引无效或未找到大厅，返回 <code>undefined</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_根据索引获得成员信息">11.9. 根据索引获得成员信息</h3>
<div class="paragraph">
<p><strong>getLobbyMemberByIndex(steamIDLobby, indexMember)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 大厅id</p>
</li>
<li>
<p><code>indexMember</code> Integer: 在 0 与 GetNumLobbyMembers 之间的索引。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获得给定索引中大厅成员的 Steam ID。 注意： 当前用户必须在大厅中才能获取该大厅中其他用户的 Steam ID。</p>
</div>
<div class="paragraph">
<p>返回一个 <a href="#SteamID">SteamID</a> 对象；如果所提供的索引无效或未找到大厅，返回 <code>undefined</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取大厅所有者">11.10. 获取大厅所有者</h3>
<div class="paragraph">
<p><strong>getLobbyOwner(steamIDLobby)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要获得其所有者的大厅的 Steam ID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>返回当前大厅所有者。 注意: 必须是大厅成员才能调用。 注意: 始终只有一位大厅所有者，如果当前所有者离开，该大厅中的另一名玩家将自动成为所有者。 在一个大厅的所有者刚离开时，其他玩家便有机会（但较少见）加入该大厅，进入大厅后，其自身便成为该大厅的所有者。</p>
</div>
<div class="paragraph">
<p>返回一个 <a href="#SteamID">SteamID</a> 对象；如果所提供的索引无效或未找到大厅，返回 <code>undefined</code>。</p>
</div>
</div>
<div class="sect2">
<h3 id="_获取大厅中的用户数量">11.11. 获取大厅中的用户数量</h3>
<div class="paragraph">
<p><strong>getNumLobbyMembers(steamIDLobby)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要获得其成员数量的大厅的 Steam ID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>获得一个大厅中的用户数。 注意： 当前用户必须在大厅中才能获取该大厅中其他用户的 Steam ID。 用于循环访问，调用此函数后，可使用 GetLobbyMemberByIndex 来获得大厅中每个成员的 Steam ID。 通过 ISteamFriends 接口可自动收到大厅其他成员的个人信息（姓名、头像等）。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Integer</code> 值，表示大厅中成员的数量，如果当前用户没有来自大厅的数据，则返回 0。</p>
</div>
</div>
<div class="sect2">
<h3 id="_邀请其他用户进入大厅">11.12. 邀请其他用户进入大厅</h3>
<div class="paragraph">
<p><strong>inviteUserToLobby(steamIDLobby, steamIDInvitee)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要邀请用户进入的大厅的 Steam ID。</p>
</li>
<li>
<p><code>steamIDInvitee</code> String: 将被邀请的用户的 Steam ID。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>邀请其他用户进入大厅。 指定用户点击了加入链接后，如果该用户在游戏中，将发送 GameLobbyJoinRequested_t 回调 ，如果游戏尚未运行，则游戏将自动通过命令行参数 +connect_lobby &lt;64-bit lobby Steam ID&gt; 启动。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值。true， 表示成功发送邀请；否则，如果本地用户不在大厅中，或无法连接至 Steam，或指定用户无效，则为 false。 注意： 此调用不检查其他用户是否被成功邀请。</p>
</div>
</div>
<div class="sect2">
<h3 id="_设置大厅是否开放">11.13. 设置大厅是否开放</h3>
<div class="paragraph">
<p><strong>setLobbyJoinable(steamIDLobby, lobbyJoinable)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 大厅的 Steam ID。</p>
</li>
<li>
<p><code>lobbyJoinable</code> Boolean: 是否允许用户加入此大厅？</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>设置一个大厅是否对其他玩家开放。 新的大厅始终默认为启用。 如果禁止加入，那么没有玩家可以加入，即便他们是好友或已受邀请。 禁止加入的大厅将不会从大厅搜索中返回。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值，表示设置是否成功。</p>
</div>
</div>
<div class="sect2">
<h3 id="_变更大厅所有者">11.14. 变更大厅所有者</h3>
<div class="paragraph">
<p><strong>setLobbyOwner(steamIDLobby, steamIDNewOwner)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要发生所有者变更的大厅的 Steam ID。</p>
</li>
<li>
<p><code>steamIDNewOwner</code> String: 要成为大厅新所有者的用户的 Steam ID，该用户必须在该大厅中。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>变更大厅所有者。 只能由大厅所有者设置。 这将针对大厅中的所有用户触发 LobbyDataUpdate_t，每位用户应更新其本地状态以反映新的所有者。 通常在所有者名称旁边显示一个皇冠图标。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值表示变更是否成功。true， 表示成功变更所有者。 false， 表示您不是大厅目前的所有者，或 steamIDNewOwner 不是大厅成员，或无法连接至 Steam。</p>
</div>
</div>
<div class="sect2">
<h3 id="_设置大厅类型">11.15. 设置大厅类型</h3>
<div class="paragraph">
<p><strong>setLobbyType(steamIDLobby, lobbyType)</strong></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>steamIDLobby</code> String: 要设置类型的大厅的 Steam ID。</p>
</li>
<li>
<p><code>lobbyType</code> <a href="#LobbyType">greenworks.LobbyType</a> 要设置的新大厅类型。</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>当使用 CreateLobby 创建大厅时也会进行此设置。 它只可由大厅所有者设置。</p>
</div>
<div class="paragraph">
<p>返回一个 <code>Boolean</code> 值表示设置是否成功。true， 表示成功；否则，如果您不是大厅所有者，则返回 false。</p>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2023-03-14 20:52:58 +0800
</div>
</div>
</body>
</html>